<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script>
        const PENDING='pending'
        const FUFILLED='fufilled'
        const REJECTED='rejected'
        class MyPromise{

            status=PENDING;
            value=undefined
            reason=undefined
            fuCallBackArr=[];
            rejeCallBackArr=[];
            constructor(constr){
                constr(this.resolve,this.reject)
            }
            resolve=(value)=>{
                if(this.status!=PENDING)return //如果状态改变了 就结束执行
                this.value=value;              //保存成功的值 
                this.status=FUFILLED            //改变成功的状态
                while(this.fuCallBackArr.length){
                    // console.log(this.fuCallBackArr.shift())
                    this.fuCallBackArr.shift()()
                }
            }
            reject=(reason)=>{
                if(this.status!=PENDING)return//如果状态改变了 就结束执行
                this.reason=reason              // 保存失败的值
                this.status=REJECTED               //改变成功的状态
                while(this.rejeCallBackArr.length){
                    this.rejeCallBackArr.shift()()
                }
            }

            then(fuCallBack,rejeCallBack){
                fuCallBack=fuCallBack?fuCallBack:value=>value
                rejeCallBack=rejeCallBack?rejeCallBack:reason=>{throw reason}
                 let promise2 =new MyPromise((resolve,reject)=>{
                    if(this.status==FUFILLED){ //如果状态成功了就调用成功的回调函数
                       setTimeout(()=>{
                            try{
                                let x= fuCallBack(this.value)
                                shopPromise(promise2,x,resolve,reject)
                            }catch(e){
                                reject(e)
                            }
                       },0)
                    }else if(this.status==REJECTED){
                        //then方法链式调用 判断是否为promise 需要判断这个promise的状态 对应这个状态我们要给自己返回的promise修改状态 如果不是直接返回
                        setTimeout(()=>{
                            try{
                                let x=rejeCallBack(this.reason)
                                shopPromise(promise2,x,resolve,reject)
                            }catch(e){
                                reject(e)
                            }
                        },0)
                    }else{
                        this.fuCallBackArr.push(()=>{
                            setTimeout(()=>{
                                try{
                                     let x= fuCallBack(this.value)
                                    shopPromise(promise2,x,resolve,reject)
                                }catch(e){
                                    reject(e)
                                }
                            },0)
                        })
                        this.rejeCallBackArr.push(()=>{
                           setTimeout(()=>{
                                try{
                                    let x=rejeCallBack(this.reason)
                                    shopPromise(promise2,x,resolve,reject)
                                }catch(e){
                                    reject(e)
                                }
                           },0)
                        })
                    }
                })
                return promise2
            }

            static all(array){
                let result=[];
                
                let numbers=0
                return new MyPromise((resolve,reject)=>{
                    function add(index,val){
                        result[index]=val
                        numbers++
                        if(numbers==array.length){
                            resolve(result)
                        }
                    }
                    for(let i=0;i<array.length;i++){
                        if(array[i] instanceof MyPromise){
                            array[i].then((value)=>{
                                add(i,value)
                            },reason=>{reject(reason)})
                        }else{
                            add(i,array[i])
                        }
                    }
                })
            }
        }
        function shopPromise(promise2,x,resolve,reject){
            if(promise2 == x){
                return reject(new TypeError('报错了'))                
            }
            if(x instanceof MyPromise){
                x.then((value)=>{
                    resolve(value)
                },(reason)=>{
                    reject(reason)
                })
            }else{
                 resolve(x)
            }
        }

        // function ohter(){
        //     return new MyPromise((resolve,reject)=>{
        //         reject('这是外部的')
        //     })
        // }
        // let pro=new MyPromise((resolve,reject)=>{
        //     setTimeout(()=>{
        //         resolve('延迟调用成功')
        //         // reject('延迟调用失败')
        //     },1000)
        // })
        // pro.then(
        //     value=>{console.log(value)},
        //     reason=>{console.log(reason)}
        // )


        // let pro=new MyPromise((resolve,reject)=>{
        //     // setTimeout(()=>{
        //         resolve('成功')
        //         // reject('延迟调用失败')
        //     // },1000)
        // })
        // let ss=pro.then(
        //     value=>{console.log(value)
        //         return ss
        //     },
        //     reason=>{console.log(reason)}
        // )
        // ss.then(
        //     value=>{console.log(value)},
        //     reason=>{console.log(reason+'第二个promise失败的状态')}
        // )

        function other() {
        return new MyPromise((resolve, reject) => {
          setTimeout(() => {
            resolve("自己延迟新创建");
          }, 2000);
        });
      }
 
      function other1() {
        return new MyPromise((resolve, reject) => {
          resolve("自己新创建");
        });
      }
        MyPromise.all(["a", "b", other(), other1(), "c"]).then((value) =>
        console.log(value)
      );
    </script>
</body>
</html>